<?
include_once("config.php");
function checaNumerico($var)
{
    if (!is_array($var)) return is_numeric($var);
    else
    {
        foreach ($var as $v)
            if (!checaNumerico($v)) return false;
        return true;
    }
}
function ListaBibliotecas()
{
    global $A_DB_TYPE, $A_DB_HOST, $A_DB_USER, $A_DB_PASS, $A_DB_DB;
    $conn = &ADONewConnection($A_DB_TYPE);
    $conn->PConnect($A_DB_HOST,$A_DB_USER,$A_DB_PASS,$A_DB_DB);
    $sql = "SELECT * FROM biblioteca";
    $rs = $conn->Execute($sql);
    if (!$rs)
        echo "Nao h&aacute; bibliotecas cadastradas!";
    else
        while (!$rs->EOF) {
            echo "<option value=\"".$rs->fields['NomeArquivo']."\">".$rs->fields['NomeBiblioteca']."</option>";
            $rs->MoveNext();
        }
    $rs->Close();
}

function Autenticacao($origem)
{
    global $logado, $id_usuario;
    if (!$logado) 
        header("Location: index.php?opcao=Login&origem=".$origem);
} // Autenticacao

function CriaPasta($Usuario)
{
    global $tipo_usuario;
    if ($tipo_usuario == "professor") {
        if (!is_dir("user/".$Usuario)) {
            mkdir("user/".$Usuario, 0700);
        }
    }
}

/* Funcoes necessarias para definir as variaveis provenientes de um formulario HTML, quando
 * a opcao $register_globals esta setada (= 1) (PHP 4.3.3)
 * Em verses anteriores de PHP as variaveis sao definidas automaticamente.
 */
function post_vars($_POST) {
	for ($i = 0; $i < count($_POST); $i++) {
		while (list($chave,$val) = each($_POST)) {
			global $$chave;
			$$chave = $val;
		}
	}
}
function get_vars($_GET) {
	for ($i = 0; $i < count($_GET); $i++) {
		while (list($chave,$val) = each($_GET)) {
			global $$chave;
			$$chave = $val;
		}
	}
}
function file_vars($_FILES) {
	global $dados,$resposta;
}
function cria_variaveis($_POST,$_GET,$_FILES) {
	post_vars($_POST);
	get_vars($_GET);
	file_vars($_FILES);
}
/* Define o idioma
 * Caso o idioma nao esteja previamente selecionado, sera utilizado o
 * idioma portugues.
 */
function define_idioma($idioma) {
    if ($idioma == "")
       include "PT_BR.php";
    else
       include $idioma;
}

//para gerar um arquivo de nome aleatrio, no seguinte formato: aaaammddhhmmssnum onde aaaa e o ano atual, 
//mm o mes, dd o dia, hh hora, mm minutos, ss segundos, e num e um numero randmico entre 1 e 99999
function gera_nome_arquivo() {
	$data = getdate();
	$arquivo = $data["year"];
	$arquivo .= $data["mon"];
	$arquivo .= $data["mday"];
	$arquivo .= $data["hours"];
	$arquivo .= $data["minutes"];
	$arquivo .= $data["seconds"];
	$arquivo .= rand(0,99999);
        return "temp/".$arquivo;
}

/** Funcao que calcula a potencia de um numero, dado a base e o expoente.
* Na versao 4.2.2 do PHP esta havendo problemas com a funcao pow.
*/
function potencia($base,$expoente) {
	$aux = 1;
	if ($expoente >= 0 ) {
		for ($i=1;$i<=$expoente;$i++) {
			$aux = $aux * $base;
		}
	} else {
		for ($i=$expoente;$i<=-1;$i++) {
			$aux = $aux / $base;
		}
	}	
	return ($aux);
}

/* Funcao para circulo de determinante, utilizada nos metodos iterativos
 * de Gauss-Seidel e Jacobi.
 */
function det() {
  global $A,$dim,$d,$p;
  for ($i=0; $i<$dim; $i++){
     for ($j=0; $j<2*$dim; $j++){
         if ($j==2*($dim-1)+$i){
            $AI[$i][$j]=1;
         } // end if
         else {
             if ($j<$dim){
                $AI[$i][$j]=$A[$i][$j];
             } // end if
             else {
                $AI[$i][$j]=0;
             } // end else
         } // end else1
      } // end for
  } // end for1
  $d=1;
  for ($k=0; $k<$dim; $k++) {
      $p=$AI[$k][$k];
      for ($i=0; $i<$dim; $i++) {
          $t[$i]=$AI[$i][$k];
      } // end for
      for ($j=$k; $j<2*$dim ;$j++) {
          $AI[$k][$j]/=$p;
          for ($i=0; $i<$dim; $i++) {
            if ($k!=$i) {
                $AI[$i][$j]-=$t[$i]*$AI[$k][$j];
            } // end if
          } // end for
      } // end for
      if ($k<($dim-1)) {
         $d*=$AI[$k+1][$k+1];
      } // end if
  } // end for1
  return($d);
} // end det

/* Triangularizacao e retrossubstituicao - utilizadas no metodo 
 * de Minimos Quadrados e metodo de Newton para Sistemas de 
 * Equacoes nao lineares
 */
function testa_denominadores ($A,$dim) {
    $continua = true;
    for ($i=0; $i<$dim; $i++) {
        if ($A[$i][$i]==0) {
            echo "<br><br>Um dos denominadores anulou-se durante o processo. Tente outras estimativas.<br><br>";
            $continua = false;
            break;
        }
    }
    return ($continua);
}

function tri($A,$dim){
    for ($k=0; $k<$dim-1; $k++) {
        for ($i=$k+1; $i<$dim; $i++) {
            $M[$i][$k]=-$A[$i][$k]/$A[$k][$k];
            for ($j=0; $j<$dim+1; $j++) {
                $A[$i][$j]+=$M[$i][$k]*$A[$k][$j];
            }
        }
    }
   return $A;
}

function retrosub($B,$dim){
   $VetX[$dim-1]=$B[$dim-1][$dim]/$B[$dim-1][$dim-1];
   for ($k=$dim-2; $k>=0; $k--) {
      $VetX[$k]=$B[$k][$dim];
      for ($i=$k+1; $i<$dim; $i++) {
         $VetX[$k]-=$B[$k][$i]*$VetX[$i];
      }
      $VetX[$k]/=$B[$k][$k];
   }
   return $VetX;
}
function quadrocomp($resp1,$it1,$resp2,$it2,$resp3,$it3,$opcaoexecucao,$parametro,$deg)
{
?>
<style>
table.bordasimples {border-collapse: collapse;}
table.bordasimples tr td {border:1px solid #000000;}
</style>
<br><br>
<table class="bordasimples">
  <tr>
    <td colspan="4" align="center">
    <b>Quadro comparativo</b>
    </td>
  </tr>
  <tr>
    <td width="20%" align="center">&nbsp;</td>
    <td width="26%" align="center">Bissec&ccedil;&atilde;o</td>
    <td width="26%" align="center">Secante</td>
    <td width="26%" align="center">Newton</td>
  </tr>
  <tr>
    <td align="center">x</td>
    <td align="center"><? echo $resp2; ?></td>
    <td align="center"><? echo $resp1; ?></td>
    <td align="center"><? echo $resp3; ?></td>
  </tr>
  <tr>
    <td align="center">f(x)</td>
    <td align="center"><? respfx($opcaoexecucao,$resp2,$parametro,$deg); ?></td>
    <td align="center"><? respfx($opcaoexecucao,$resp1,$parametro,$deg); ?></td>
    <td align="center"><? respfx($opcaoexecucao,$resp3,$parametro,$deg); ?></td>
  </tr>
  <tr>
    <td align="center">Itera&ccedil;&otilde;es</td>
    <td align="center"><? echo $it2; ?></td>
    <td align="center"><? echo $it1; ?></td>
    <td align="center"><? echo $it3; ?></td>
  </tr>
</table>
<?
}
function respfx($opcao,$x,$parametro,$deg)
{
    if ($opcao == 0)
    {
        $soma=0;
        for ($i=0; $i<$deg+1;$i++)
        {
            $soma+=$parametro[$i]*potencia($x,$deg-$i);
        }
        echo $soma;
    }
    elseif ($opcao == 1)
    {
        $func_aux=normaliza_funcao($parametro).";";
        eval('$verif_result='.$func_aux);
        echo $verif_result;
    }
}
function verifica_polino($coef,$deg,$xmedio)
{
    global $msg;
	echo "<br><br>\n".$msg->get('Verificacao_Resultado').":<br>\nf(x) = ";
	$verif_result = 0;
	for ($i = 0; $i < $deg+1; $i++)
	{
		$verif_result+=$coef[$i] * potencia($xmedio,$deg-$i);
		echo ($coef[$i] < 0)?'-':'+';
		echo " ".abs($coef[$i]);
		if ($i != $deg) echo " * (".$xmedio.")<sup>".($deg-$i)."</sup>";
	}
	echo "<br>\nf(x) = $verif_result";
}
function verifica_funcao($funcao,$xmedio)
{
    global $msg;
	$func_aux=normaliza_funcao($funcao).";";
	$x = $xmedio;
	eval('$verif_result='.$func_aux);
	echo "<br><br>\n".$msg->get('Verificacao_Resultado').":<br>\nf(x) = ".str_replace('x',$xmedio,$funcao)."<br>\nf(x) = ".$verif_result;
}
function seqlsol($A,$VetX,$dim,$T,$erro=0.00000001)
{
    global $msg;
	echo "<br><br>";
	for ($i=0; $i<$dim; $i++) {
		$C[$i]=0;
		for ($k=0;$k<$dim;$k++) {
			$C[$i]=$C[$i]+$A[$i][$k]*$VetX[$k];
		}
	}
	for ($i=0; $i<$dim; $i++) $T[$i]=$T[$i]+0.0;
	echo "<b>".$msg->get('Substituicao_Vetor').":</b><br>";
	echo "<table border=\"0\">";
	for ($i=0; $i<$dim; $i++) {
		echo "<tr>";
		for ($j=0; $j<$dim; $j++) {
			echo "<td width=\"85\" align=\"center\">";
			echo $A[$i][$j]." * (".round($VetX[$j],4).")";
			if ($j != ($dim-1))
			{
				echo "</td><td width=\"20\" align=\"center\">+";
			}
			echo "</td>";
		}
		echo "<td width=\"20\" align=\"center\"> = </td><td width=\"45\" align=\"center\">".$C[$i]."</td>";
		if (abs($C[$i] - $T[$i]) < $erro) echo "<td><font color=green>v</font>";
		else echo "<td><font color=red>x</font></td>";
		echo "</tr>";
	}
	echo "</table>";
}
/** Verifica a convergencia do sistema nos metodos iterativos de Gauss-Seidel e Jacobi */
function verificaConvergencia () {
	global $A, $T, $dim,$msg;
	$pode = 1;
	//verifica se a matriz e diagonal dominante
	for ($i=0; $i<$dim; $i++) {
		$cont[$i] = 0; //armazena o somatorio dos |a ij|, para i!=j, para cada i
		for ($j=0; $j<$dim; $j++) {
			if ($i != $j) {
			   $cont[$i] = abs($cont[$i]) + abs($A[$i][$j]); // somatorio dos mdulos de A ij
			} //if
		} //for j
		// se modulo de A ii e menor que o somatorio dos modulos de A ij para i != j
		if (abs($A[$i][$i]) <= $cont[$i]) { 
		// entao a linha i nao e diagonal dominante
			for ($k = $i + 1; $k<$dim; $k++) { //procura a partir da linha i+1
				$cont_aux = 0; // auxiliar para calcular o somatorio na linha $k como se o piv fosse na coluna i
				for ($j=0; $j<$dim; $j++) {
					if ($i != $j) {
				   		$cont_aux += abs($A[$k][$j]); // somatorio dos mdulos de A kj
					} //if
				} //for j
				//se satisfaz a condicao diagonal dominante para a linha i, trocando linha i por linha k
				if (abs($A[$k][$i]) > $cont_aux) {
				// entao troca a linha i com a linha k
					echo $msg->get("Trocou_Linha")." ".($i+1)." ".$msg->get('Pela_Linha')." ".($k+1)."<br><br>";
					for ($l=0; $l<$dim; $l++) {
						$aux = $A[$k][$l];
						$A[$k][$l] = $A[$i][$l];
						$A[$i][$l] = $aux;
					} // end for l
					$aux = $T[$k];
					$T[$k] = $T[$i];
					$T[$i] = $aux;
					$k = $dim + 1; // sai do for k; 
				} // end if
			} // end for k
			// se nao houve troca de linha alguma
			if ($k == $dim) { 
				// entao nao e diagonal dominante
				//echo "Aviso: A matriz nao e diagonal dominante. Nao ha garantias de convergencia do metodo. <br><br>";
				//break;
				return false;
			} // end if
		} // end if
	} //for i
	return true;
} //end function

//Verifica a convergencia com o criterio de Sassenfeld para o metodo iterativo de Gauss-Seidel
function sassenfeld($A,$dim)
{
	$indmaior=0; //inicia o indice da maior soma com '0'
	for ($i = 0; $i < $dim; $i++)
	{
		$beta[$i]=0; //inicializa a soma como 0
		for ($j = 0; $j <= ($i - 1); $j++) $beta[$i]+=abs($A[$i][$j])/abs($A[$i][$i])* $beta[$j];
		for ($j = $i+1; $j < $dim; $j++) $beta[$i]+=abs($A[$i][$j])/abs($A[$i][$i]);
		if ($beta[$indmaior] < $beta[$i]) $indmaior=$i; //verifica o maior indice
	}
	if ($beta[$indmaior] >= 1) //caso o maior indice seja < 1, o criterio nao e satisfeito
	{
		return false;
	}
	return true;
}

//Verifica a convergencia com o criterio das colunas para o metodo iterativo de Jacobi
function critcoluna($A,$dim)
{
	$indmaior=0; //inicia o indice da maior soma com '0'
	for ($j=0; $j<$dim; $j++)
	{
		$soma[$j]=0; //inicializo a soma
		for ($i=0; $i<$dim; $i++) if ($i != $j) $soma[$j]+=abs($A[$i][$j])/abs($A[$i][$i]);
		if ($soma[$j] > $soma[$indmaior]) $indmaior=$j; //verifico se a soma calculada e maior que maior registrada
	}
	if ($soma[$indmaior] < 1) return true; //soma do maior < 1, satisfaz o criterio das colunas
	return false; //caso contrario, nao satisfaz o criterio
}

/************************Funcoes de integracao numerica************************/

/* Retorna o valor da funcao em um ponto
 * (utilizado nos programas de integracao numerica)
 */
function evalf($x,$deg,$coef){
   $f=0;
   for($i=0;$i<$deg;$i++){
      $f=$f+$coef[$i]*potencia( $x, $deg- $i);
   }
   $f=$f+$coef[$deg];
   return $f;
}
/* Metodo do trapezio utilizado em minimos quadrados (Ajuste de Dados)
 * polinomial
 */
function trapezio_polinomial($a,$b,$vn,$coef,$deg){
   $fa=evalf($a,$deg,$coef);
   $fb=evalf($b,$deg,$coef);
   $delta=($b-$a)/$vn;
   for($i=0;$i<$vn-1;$i++){
      $v[$i]=evalf($a+(($i+1)*$delta),$deg,$coef);
   }
   $sum=0;
   $sum=$fa+$fb;
   for($i=0;$i<$vn-1;$i++){
      $sum=$sum+(2*$v[$i]);
   }
   $aprox=(($b-$a)/(2*$vn))*$sum;
   return $aprox;
}
/*
//metodo de Simpson - Integracao numerica
function simpson($a,$b,$vn,$coef,$deg){
   $fa=evalf($a,$deg,$coef);
   $fb=evalf($b,$deg,$coef);
   $delta=($b-$a)/$vn;
   for($i=0;$i<$vn-1;$i++){
      $v[$i]=evalf($a+(($i+1)*$delta),$deg,$coef);
   }
   $sum=0;
   $sum=$fa+$fb;
   for($i=0;$i<$vn-1;$i++){
      if((($i+1)%2)==0)
         $sum=$sum+(2*$v[$i]);
      else
         $sum=$sum+(4*$v[$i]);
   }
   $aprox=(($b-$a)/(3*$vn))*$sum;
   return $aprox;
}
//metodo de Richardson - Integracao numerica
function richardson($a,$b,$vn,$vm,$coef,$deg){
   $integ1=simpson($a,$b,$vn,$coef,$deg);
   $integ2=simpson($a,$b,$vm,$coef,$deg);
   $resp=$integ2 + ((potencia($vn,4)/(potencia($vm,4)-potencia($vn,4)))*($integ2-$integ1));
   return $resp;
}
//metodo de Romberg - Integracao numerica
function romberg($a,$b,$vn,$vm,$coef,$deg){
   $integ1=trapezio($a,$b,$vn,$coef,$deg);
   $integ2=trapezio($a,$b,$vm,$coef,$deg);
   $resp=$integ2 + ((potencia($vn,2)/(potencia($vm,2)-potencia($vn,2)))*($integ2-$integ1));
   return $resp;
}
*/

/* Normaliza  a funcao de entrada, para a sintaxe compreendida pelo php.
 * Utilizada nos programas que possuem entrada de uma funcao f(x).
 */
function normaliza_funcao($funcao) {
   for ($i=0; $i<strlen($funcao); $i++) {
      if ($funcao[$i] == 'x') {
          $funcao =  substr_replace($funcao, '$', $i, 0);
          $i = $i + 2;
      }
      if ($funcao[$i] == 'E') {
          $funcao =  substr_replace($funcao, 'M_', $i, 0);
          $i = $i + 3;
      }
      if ( ($funcao[$i] == 'P') and ($funcao[$i+1] == 'I') ) {
          $funcao =  substr_replace($funcao, 'M_', $i, 0);
          $i = $i + 4;
      }

   }
   return $funcao;
}
/* Metodo do trapezio utilizado tambem em minimos quadrados 
 * (Ajuste de Dados)
 */
function trapezio($funcao,$a,$b,$n) {
   eval ('$x=$a;$fa='.$funcao); //calcula o valor da funcao no ponto x = a
   eval ('$x=$b;$fb='.$funcao); //calcula o valor da funcao no ponto x = b
   $delta=($b-$a)/$n;
   for($i=0;$i<$n-1;$i++){
      eval ('$x=$a+($i+1)*$delta;$v[]='.$funcao);
   }
   $sum=0;
   $sum=$fa+$fb;
   for($i=0;$i<$n-1;$i++){
      $sum=$sum+(2*$v[$i]);
   }
   $aprox=(($b-$a)/(2*$n))*$sum;
   return $aprox;
}
/* Metodo de Simpson - Integracao numerica 
 */
function simpson($funcao,$a,$b,$n){
   eval ('$x=$a;$fa='.$funcao); //calcula o valor da funcao no ponto x = a
   eval ('$x=$b;$fb='.$funcao); //calcula o valor da funcao no ponto x = b
   $delta=($b-$a)/$n;
   for($i=0;$i<$n-1;$i++){
      eval ('$x=$a+($i+1)*$delta;$v[]='.$funcao);
   }
   $sum=0;
   $sum=$fa+$fb;
   for($i=0;$i<$n-1;$i++){
      if((($i+1)%2)==0)
         $sum=$sum+(2*$v[$i]);
      else
         $sum=$sum+(4*$v[$i]);
   }
   $aprox=(($b-$a)/(3*$n))*$sum;
   return $aprox;
}
/* Metodo de Richardson - Integracao numerica 
 */
function richardson($funcao,$a,$b,$vn,$vm){
   $integ1=simpson($funcao,$a,$b,$vn);
   $integ2=simpson($funcao,$a,$b,$vm);
   $resp=$integ2 + ((potencia( $vn,4)/(potencia( $vm,4)-potencia( $vn,4)))*($integ2-$integ1));
   return $resp;
}
/* Metodo de Romberg - Integracao numerica
 */
function romberg($funcao,$a,$b,$vn,$vm){
   $integ1=trapezio($funcao,$a,$b,$vn);
   $integ2=trapezio($funcao,$a,$b,$vm);
   $resp=$integ2 + ((potencia( $vn,2)/(potencia( $vm,2)-potencia( $vn,2)))*($integ2-$integ1));
   return $resp;
}
/* Funcao para circulo da derivada no ponto x 
*/
function deriva($funcao,$k,$t,$xo,$erro,$imprime) {
   // parametro imprime define se os resultados parciais sao exibidos na tela
   $para = false;
   $j = 1;
   //$hk = bcpow( $t, -$j, $t); //** Substituido por funcoes sem a biblioteca bcmath, podem haver complicações **
   $hk = round(pow( $t, -$j),$t);
   if ($imprime == "sim") {
      echo "k = ".$j."<br>";
      echo "h(k) = ".$t."<sup>-".$j."</sup> = ".round($hk,10)." <br>";
   } //end if
   eval ('$x=$xo-$hk;$f0='.$funcao);
   eval ('$x=$xo+$hk;$f1='.$funcao);
   $derivada0 = ($f1-$f0) / (2*$hk);
   if ($imprime == "sim") {
       echo "f '(".$xo.") = (f(".$xo."+".round($hk,10).") - f(".$xo."-".round($hk,10).")) / ".round($hk,10)." = ".round($derivada0,10)."<br><br>";
   } //end if
   while ( ($para == false) and ($j <= $k) ) {
      $j++;
      $hk = potencia( $t, -$j);
      eval ('$x=$xo-$hk;$f0='.$funcao);
      eval ('$x=$xo+$hk;$f1='.$funcao);
      $derivada1 = ($f1-$f0) / (2*$hk);
      if ( abs($derivada1-$derivada0) < $erro ) {
         $para = true;
      } //end if
      $derivada0 = $derivada1;
      if ($imprime == "sim") {
	  echo "k = ".$j."<br>";
          echo "h(k) = ".$t."<sup>-".$j."</sup> = ".round($hk,6)." <br>";
          echo "f '(".$xo.") = (f(".$xo."+".round($hk,10).") - f(".$xo."-".round($hk,10).")) / ".round($hk,10)." = ".round($derivada0,10)."<br><br>";
      } //end if
   } //end while
   if ( ($para == true) and (is_nan($derivada0) == 0) )
      $resposta = $derivada0;
   else if ( ($j > $k) or (is_nan($derivada0) == 1) )
      $resposta = "erro";
   return $resposta;
}

/* Funcao para enumerar raizes nos programas de resolucao de 
 * Equacoes nao-lineares (secante, bisseccaoo e Newton)
 */
function enumera_raizes($coef,$grau) {
   global $transf_negativo, $transf_positivo;
   $complexa = "nao";
   for ($i=0; $i <= $grau; $i++) { // verifica se possui raizes complexas
       if ( ( ($i > 0) and ($i < $grau) and ( potencia( $coef[$i],2) <= $coef[$i+1]*$coef[$i-1]) )
       or ( ($i > 0) and ($i < $grau) and ($coef[$i]==0) and ($coef[$i+1]*$coef[$i-1] > 0) )
       or ( ($i < $grau) and ($coef[$i]==0) and ($coef[$i+1]==0) ) )
          $complexa = "sim";
   }
   for ($i=0; $i <= $grau; $i++) {
       $vet1[$i] = $coef[$i];
       if ( ((($grau-$i) % 2)!=0) and ($coef[$i]!=0) )
          $vet2[$i] = -$coef[$i];
       else $vet2[$i] = $coef[$i];
   }
   $gr = $grau;
   for ($i=0; $i <= $gr; $i++) { // vetor dos sinais dos coeficientes nao nulos para "x"
       if ($vet1[$i] == 0) {
          while ($vet1[$i] == 0) {
	     for ($j=$i;$j<=$gr;$j++)
	         @$vet1[$j] = $vet1[$j+1];
	     $gr--;
          }
       }
   }
   $transf_positivo = 0;
   for ($i=0; $i < $gr; $i++) { // verifica a possibilidade de raizes reais positivas
       if ($vet1[$i] != 0)
          //if ( ( ($vet1[$i] > 0) and ($vet1[$i+1] < 0) ) or ( ($vet1[$i] < 0) and ($vet1[$i+1] > 0) ) )
          if (($vet1[$i] * $vet1[$i+1]) < 0)
             $transf_positivo++;
   }
   $gr = $grau;
   for ($i=0; $i <= $gr; $i++) { // vetor dos sinais dos coeficientes nao nulos para "-x"
       if ($vet2[$i] == 0) {
          while ($vet2[$i] == 0) {
	     for ($j=$i;$j<=$gr;$j++)
	         @$vet2[$j] = $vet2[$j+1];
	     $gr--;
          }
       }
   }
   $transf_negativo = 0;
   for ($i=0; $i < $gr; $i++) { // verifica a possibilidade de raizes reais negativas
       if ($vet2[$i] != 0)
          //if ( ( ($vet2[$i] > 0) and ($vet2[$i+1] < 0) ) or ( ($vet2[$i] < 0) and ($vet2[$i+1] > 0) ) )
          if (($vet2[$i] * $vet2[$i+1]) < 0)
             $transf_negativo++;
   }
   //montar tabela de possibilidades
   if ($complexa == "nao") {
      $k = 0;
      for ($contador1 = $transf_positivo; $contador1 >= 0; $contador1-=2) {
            $k++;
            $tabela[$k]["positiva"] = $contador1;
            //$tabela[$k]["negativa"] = $contador2;
            $tabela[$k]["negativa"] = $grau-$contador1;
            $tabela[$k]["complexa"] = 0;
      }
      for ($contador2 = $transf_negativo; $contador2 >= 0; $contador2-=2) {
	     //if ($contador1+$contador2==$grau) { // o numero de raizes deve ser igual ao valor do grau da funcao
            $tmp=false;
            for ($j = 1; $j <= $k; $j++)
            {
                  if ($tabela[$j]["negativa"] == $contador2) $tmp=true;
            }
            if (!$tmp)
            {
                  $k++;
                  $tabela[$k]["negativa"] = $contador2;
                  $tabela[$k]["positiva"] = $grau-$contador2;
                  $tabela[$k]["complexa"] = 0;
            }
      }
      $tabela[0]["positiva"] = $k; //primeira linha serve como contador
   }
   else if ($complexa == "sim") {
      $k = 0;
      for ($contador1 = $transf_positivo; $contador1 >= 0; $contador1-=2) {
          for ($contador2 = $transf_negativo; $contador2 >= 0; $contador2-=2) {
	    if ($grau-($contador1+$contador2) != 0) { /*o num. de raizes deve ser igual ao valor do grau da funcao.
            Se ha raizes complexas, entao o numero de raizes reais nao deve ser igual ao valor do grau da funcao*/
	       $k++;
	       $tabela[$k]["positiva"] = $contador1;
	       $tabela[$k]["negativa"] = $contador2;
	       $tabela[$k]["complexa"] = $grau - ($contador1 + $contador2);
	    }
	  }
      }
      $tabela[0]["positiva"] = $k; //primeira linha serve como contador
   }
   return $tabela;
}

/* Funcao para encontrar as cotas nos programas de resolucao de 
 * Equacoes nao-lineares (secante, bisseccao e Newton)
 */
function cotas($coef,$grau,$sinal) {
    //Localizar as raizes positivas de p(x) = 0
    if ($sinal == "-") {
        for ($i=0; $i<=$grau; $i++) {
           if ( ( ($grau-$i) %2 ) != 0 )
              $coef[$i] = -$coef[$i];
           $coef[$i] = -$coef[$i];
	}
    }
    $k = 0;
    $para = "false";
    $R[$grau]=-1;
    while ( ($R[$grau] < 0) and ($para=="false") ) {
       $k = $k + 1;
       $para = "true";
       $q[0] = 0;
       for ($i=0; $i<=$grau; $i++) {
	  if ($i < $grau)
	     $q[$i+1] = $k*($coef[$i] + $q[$i]);
	  $R[$i] = $coef[$i] + $q[$i];
	  if ($i != 0)
	     if ($q[$i] < 0)
	        $para = "false";
       }
       if ($k == 1000) {
	  $para = "true";
	  $k = 0;
       }
    }
    return $k;
}

/* Retorna o valor de uma funcao polinomial no ponto.
 * Utilizada nos metodos de resolucao de eq. nao lineares.
 */
function Resolve($cf,$grau,$x){
   $aux=0;
   for($i=0;$i<$grau;$i++){
      $aux=$aux+$cf[$i]*potencia( $x, $grau -  $i);
   }
   $aux=$aux+$cf[$grau];
   return $aux;
}

/* Funcoes utilizadas no metodo de Newton para Sistemas de Equacoes nao-lineares 
 */

/* Retorna a Jacobiana de uma funcao vetorial (Rn -> Rn)
 */
function Jacobiana($matriz,$dim) {
   for ($i=0; $i<$dim; $i++) {
        for ($j=0; $j<$dim; $j++) {
           $jacob[$i][$j]["coef"] = $matriz[$i][$j]["coef"] * $matriz[$i][$j]["grau"];
           $jacob[$i][$j]["grau"] = $matriz[$i][$j]["grau"] - 1;
        }
   }
   return $jacob;
}

/* Atualiza o valor da funcao para um vetor de estimativas para x. 
 */
function atualiza_f($matriz,$dim,$vtx) {
   for ($i=0; $i<$dim; $i++) {
       $f[$i] = $matriz[$i][$dim]["coef"];
   }
   for ($i=0; $i<$dim; $i++) {
        for ($j=0; $j<$dim; $j++) {
           $f[$i] = $f[$i] + $matriz[$i][$j]["coef"] * potencia( $vtx[$j], $matriz[$i][$j]["grau"]);
        }
        $f[$i] = -$f[$i];
   }
   return $f;
}

/* Atualiza o valor da matriz jacobiana para um vetor de estimativas para x.
 */
function atualiza_matriz_jacobiana($jacob,$dim,$vtx) {
   for ($i=0; $i<$dim; $i++) {
        for ($j=0; $j<$dim; $j++) {
           $mat[$i][$j] = $jacob[$i][$j]["coef"] * potencia( $vtx[$j], $jacob[$i][$j]["grau"]);
        }
   }
   return $mat;
}

/* Testa se o metodo de Newton para Sist. de Equacoes
 * nao-lineares convergiu ou nao.
 */
function convergiu($f,$dim,$t){
    $cont = 0;
    for ($i=0; $i<$dim; $i++) {
        if (round($f[$i],$t) == 0) $cont = $cont + 1;
    }
    if ($cont == $dim) return "sim";
    else return "nao";
}

/********** funcoes para os programas de aritmetica em ponto flutuante ***********/

/* Converte um numero em decimal para um numero numa determinada 
 * base (entre 2 e 9).
 */
function decimal_to_base_x($num,$x,$mant) {
	if ( ($x>=2) and ($x<=9) ) {
		//divide o numero entre a parte inteira e fracionaria (quando existe)
		@list($parte1,$parte2) = explode(".",$num);
		if (strlen($parte2) == 0 ) {
		        //conversao de numero decimal inteiro
			return base_convert($num,10,$x);
		} //end if
		else {
		// conversao de numero decimal com parte fracionaria
			//parte fracionaria recebe "0." no inicio do numero
			$aux = substr_replace($parte2, '0.', 0, 0);
			$convert = "0.";
			/* converte a parte fracionaria do numero de base
			 * decimal para a base $x (entre 2 e 10)
			 */
			for ($i=0;$i<$mant+10;$i++) {
				$aux = $aux * $x;
				$convert .= floor($aux);
				$aux = $aux - floor($aux);
			} //end for
			// converte a parte inteira do numero de base decimal para base $x
			$parte1 = base_convert($parte1,10,$x);
			//une as partes inteira e decimal
			$convert = substr_replace($convert,$parte1, 0, 1);
			return($convert);
		} //end else
	} //end if
	else return($num);
} //end function

/* Converte um numero numa determinada base (entre 2 e 9) para um numero em decimal.
 * Apenas para numeros normalizados (na forma 0.xxxxx);
 */
function base_x_to_decimal($num,$x,$mant,$grau) {
	$aux = 1;
	$result = 0;
        // percorre cada algarismo da mantissa
	for ($j=2; $j<strlen($num)-1; $j++) {
		$result = $result +  $num[$j] / potencia( $x, $aux);
		$aux++;
	} //end for
	$result = ($result + $num[$j]/potencia( $x, $aux) ) * potencia( $x, $grau);
	return $result;
} //end function


/* Normaliza um numero em ponto flutuante para a forma 
 *  0.xxxx "vezes" "base elevado a expoente".
 */
function normaliza_num($num,$base,$mant,$grau) {
    global $msg;
    $resp["grau"] = $grau;
	//separa as partes inteira e decimal do numero
//	list ($int,$frac) = explode (".",$num);
    $tmp = explode(".",$num);
    if (sizeof($tmp) > 1) $frac = $tmp[1];
    else $frac = "";
    $int=$tmp[0];
    $i = 0;
	//localiza onde esta o ponto
	while ( ($i < strlen($num)) and ($num[$i] != ".") ) {
              $i++;
        } //end while
        // caso o numero possua apenas a parte inteira, eh necessario
	// incluir .0 para efetuar os circulos
	if (strlen($frac)==0) {
        	   //une as partes inteira e decimal
		   $num = substr_replace($num,".0",strlen($num),0);
		   //localiza a coordenada do ponto na string do numero
		   $i = strlen($num)-2;
        } //end if
	//normalizar o numero cuja parte inteira seja diferente de 0
	if ($int != 0) {
	      while ($int!=0) {
		  $num[$i] = $num[$i-1];
		  $num[$i-1] = ".";
                  $grau++;
		  $i--;
		  list ($int,$frac) = explode (".",$num);
	      } //end while
	      $num = "0".$num;
	      $resp["grau"] = $grau;
	} //end if
	// normalizar o numero cuja parte inteira seja igual a 0 e o
	// primeiro digito aps a virgula igual a 0
	else if ($frac[0] == "0") {
	      while ($frac[0] == "0") {
	           $num[$i] = $num[$i+1];
		   $num[$i+1] = ".";
		   $grau--;
		   $num = substr_replace($num,"",0,1);
	           list ($int,$frac) = explode (".",$num);
	      } //end while
	      //caso a parte fracionaria seja igual a zero
	      if (strlen($frac) == 0) {
	           $num = substr_replace($num,"0",strlen($num),0);
		   $grau = 0;
	      } //end if
	      $resp["grau"] = $grau;
	} //end else
        list ($int,$frac) = explode (".",$num);
	// numero de casas decimais eh maior que a mantissa do sistema de ponto flutuante
	if (strlen($frac) > $mant) {
		$aux ="";
		//reduz para o numero de casas decimais definido na mantissa do sistema
		while (strlen($frac) > $mant) {
		       $aux = substr_replace($aux,$frac[strlen($frac)-1],0,0);
		       $frac = substr_replace($frac,"",strlen($frac)-1,1);
		} //end while
		$num = substr_replace($frac,$int.".",0,0);
		echo $num."<font color=red>".$aux." </font> x ".$base."<sup>".$grau."</sup><br>";
		echo "<font color=red>".$msg->get("SISTEMAPF_MSG_20")." ".$mant." ".$msg->get("SISTEMAPF_MSG_21")."</font> <br><br>";
	} //end if
	list ($int,$frac) = explode(".",$num);
	//retira os zeros nao significativos na parte fracionaria que possam aparecer
	if ($num[strlen($num)-1] == "0") {
		list ($int,$frac) = explode(".",$num);
		// enquanto o ltimo digito da parte fracionaria for igual a zero
		while ($num[strlen($num)-1] == "0") {
			$num = substr_replace($num,"",strlen($num)-1,1);
 			list ($int,$frac) = explode(".",$num);
		} //end while
	} //end if
	if (strlen($frac)<$mant) {
		/* preenche a parte fracionaria dos numeros com zeros
		 * a partir da direita.
		 * caso o numero de digitos seja menor que o valor da mantissa
		 * -para fins de visualizacao do problema-.
		 */
		while (strlen($frac)<$mant) {
			$num = substr_replace($num,"0",strlen($num),0);
			list ($int,$frac) = explode(".",$num);
		} //end if
	} //end if
	$resp["num"] = $num;
	return $resp;
} //end function

/* Verifica se um numero normalizado esta na regiao de underflow ou overflow.
 */
function verifica_overflow_underflow($grau,$expmin,$expmax) {
	if ( ($grau <= $expmax) and ($grau >= $expmin) ) {
		return ("ok");
	}
	if ($grau > $expmax) {
	    return ("erro_over");
	}
	if ($grau < $expmin) {
	    return ("erro_under");
	}
} //end function

/*
	This function is meant to be a drop-in replacement for those
	people who don't have bcmath functionality in their PHP
	distribution. It probably has problems, and the best solution
	is to build yourself a version with bcmath support. Barring
	this, you can use this hack.

		- Jeff
*/
/*
function bcadd ($left, $right, $scale=0) {
	// first add the two numbers
	$sum = (double)($left + $right);

	// check for a dot in the number
	if (strpos($sum, ".") === false) {
		// not found, integer
		$int_part = $sum;
		$real_part = 0;
	} else {
		// if not, we split
		list ($int_part, $real_part) = explode (".", $sum);
	} // end checking for a dot

	// handle scale of 0
	if ($scale == 0) return $int_part;

	// handle real parts that need more precision
	if ($scale > strlen($real_part)) {
		for ($i=0;$i<=($scale - strlen($real_part));$i++)
			$real_part .= "0";
	} // end checking for more precision needed

	// return built string
	return $int_part . "." . substr($real_part, 0, $scale);
} // end function bcadd
 */

/* Soma dois numeros em ponto flutuante, dado o sistema de ponto flutuante
 * F = (base,mant,expmin,expmax) e os numeros num1, num2 (em decimal).
 */

function somaPF($num1,$num2,$base,$mant,$expmin,$expmax) {
    global $msg;
	$prossegue = "sim";
	echo "<b>".$msg->get("SOMAPF_MSG_11")."</b> <br><br>";
	echo "F = (b,m,e<sub>1</sub>,e<sub>2</sub>)<br><br>";
	echo "b = ".$base."&nbsp&nbsp m = ".$mant."&nbsp&nbsp e<sub>1</sub> = ".$expmin."&nbsp&nbsp e<sub>2</sub> = ".$expmax."<br><br>";
	echo "<b>".$msg->get("SOMAPF_MSG_12")."</b> <br><br>";
	echo "X<sub>1</sub> = ".$num1."<sub>10</sub><br><br>";
	echo "X<sub>2</sub> = ".$num2."<sub>10</sub><br><br>";
	echo "<b>".$msg->get("SOMAPF_MSG_13")." ".$base.":</b> <br><br>";
	$num1 = decimal_to_base_x($num1,$base,$mant);
	$num2 = decimal_to_base_x($num2,$base,$mant);
	echo "X<sub>1</sub> = ".$num1."<sub>".$base."</sub><br><br>";
	echo "X<sub>2</sub> = ".$num2."<sub>".$base."</sub><br><br>";
	echo "<b>".$msg->get("SOMAPF_MSG_14")."</b> <br><br>";
	$valor1 = normaliza_num($num1,$base,$mant,0);
	$valor2 = normaliza_num($num2,$base,$mant,0);
	$erro1 = verifica_overflow_underflow($valor1["grau"],$expmin,$expmax);
	$erro2 = verifica_overflow_underflow($valor2["grau"],$expmin,$expmax);
	echo "X<sub>1</sub> = ".$valor1["num"]." x ".$base."<sup>".$valor1["grau"]."</sup>";
	if ($erro1 != "ok") {
		if ($erro1 == "erro_over") {
			echo "<font color=red>".$msg->get("SOMAPF_MSG_15")." ".$valor1["grau"]." > ".$expmax." </font>";
		} //end if
		if ($erro1 == "erro_under") {
			echo "<font color=red>".$msg->get("SOMAPF_MSG_16")." ".$valor1["grau"]." < ".$expmin." </font>";
		} //end if
		$prossegue = "nao";
	} //end if
	echo "<br><br>";
	echo "X<sub>2</sub> = ".$valor2["num"]." x ".$base."<sup>".$valor2["grau"]."</sup>";
	if ($erro2 != "ok") {
		if ($erro2 == "erro_over") {
			echo "<font color=red>".$msg->get("SOMAPF_MSG_15")." ".$valor2["grau"]." > ".$expmax." </font>";
		} //end if
		if ($erro2 == "erro_under") {
			echo "<font color=red>".$msg->get("SOMAPF_MSG_16")." ".$valor2["grau"]." < ".$expmin." </font>";
		} //end if
		$prossegue = "nao";
	} //end if
	echo "<br><br>";
        // verifica se e possivel somar os numeros
	if ( ($valor1["grau"] < $valor2["grau"]) or ( ($valor1["grau"] == $valor2["grau"]) and ($valor1["num"] < $valor2["num"]) ) ) {
		$aux1 = $valor1["num"];
		$aux2 = $valor1["grau"];
		$valor1["num"] = $valor2["num"];
		$valor1["grau"] = $valor2["grau"];
		$valor2["num"] = $aux1;
		$valor2["grau"] = $aux2;
		echo "<font color=red> ".$msg->get("SOMAPF_MSG_17")." </font><br><br>";
		echo $msg->get("SOMAPF_MSG_18")." <br><br>";
		echo "X<sub>1</sub> = ".$valor1["num"]." x ".$base."<sup>".$valor1["grau"]."</sup><br><br>";
		echo "X<sub>2</sub> = ".$valor2["num"]." x ".$base."<sup>".$valor2["grau"]."</sup><br><br>";
	} //end if
	if ($prossegue == "nao") {
		echo "<font color=red>".$msg->get("SOMAPF_MSG_19")."</font><br><br>";
	} //end if
	if ($prossegue == "sim") {
		echo "<b>".$msg->get("SOMAPF_MSG_20")."</b> <br><br>";
		echo "( ".$valor1["num"]." x ".$base."<sup>".$valor1["grau"]."</sup> + ";
		echo $valor2["num"]." x ".$base."<sup>".$valor2["grau"]."</sup> ) <br><br>";
		echo "g = e - f <br>";
		echo "g = (".$valor1["grau"].") - (".$valor2["grau"].") = ".($valor1["grau"] - $valor2["grau"])."<br><br>";
		$g = $valor1["grau"] - $valor2["grau"];
		if ($g >= $mant) { // se g e igual ou maior que a mantissa, entao o resultado sera o valor de x
			echo "<b>".$msg->get("SOMAPF_MSG_21")." >= ".$mant." ".$msg->get("SOMAPF_MSG_22")."</b><br><br>";
			echo "<font color=blue> ".$msg->get("SOMAPF_MSG_10")." x<sub>1</sub>= ".$valor1["num"]." x ".$base."<sup>".$valor1["grau"]."</sup> = ";
			//calcular o valor da resposta na base decimal
//			$result = base_x_to_decimal($res["num"],$base,$mant,$res["grau"]);
			$result = base_x_to_decimal($valor1["num"],$base,$mant,$valor1["grau"]);
			echo $result.".<br><br></font>";
		} //end if
		else { //caso g seja menor que a mantissa, entao e preciso seguir o seguinte algoritmo
			echo "<b>".$msg->get("SOMAPF_MSG_21")." < ".$mant." ".$msg->get("SOMAPF_MSG_22")."</b><br><br>";
			echo "<b>".$msg->get("SOMAPF_MSG_23")."<br><br></b>";
			echo "X<sub>1</sub> = ";
			for ($i=2; $i<strlen($valor1["num"]); $i++) {
				echo $valor1["num"][$i]." &nbsp ";
			} //end for
			echo "| &nbsp  0 .. 0 &nbsp x ".$base."<sup>".$valor1["grau"]."</sup><br>";
			echo "X<sub>2</sub> = ";
			for ($i=2; $i<strlen($valor2["num"]); $i++) {
				echo $valor2["num"][$i]." &nbsp ";
			} //end for
			echo "| &nbsp  0 .. 0 &nbsp x ".$base."<sup>".$valor2["grau"]."</sup><br><br>";
			echo "<b>".$msg->get("SOMAPF_MSG_24")." ".$g." ".$msg->get("SOMAPF_MSG_25")."<br><br></b>";
			for ($i=0;$i<$g;$i++) { //desloca num2 de g casas a direita
				$valor2["num"] = substr_replace($valor2["num"],"0",2,0);
			} //end for
			echo "X<sub>1</sub> = ";
			for ($i=2; $i<strlen($valor1["num"]); $i++) { //imprime num1
				echo $valor1["num"][$i]." &nbsp ";
			} //end for
			echo "| &nbsp  ";
			for ($i=0;$i<$g;$i++) {  //imprime g 0's depois de num1
				echo "0 &nbsp ";
			} //end for
			echo " &nbsp x ".$base."<sup>".$valor1["grau"]."</sup> <br>";
			$temp = "";
			echo "X<sub>2</sub> = ";
			//imprime os "mant" primeiros digitos de num2 (tamanho da mantissa)
			for ($i=2; $i<strlen($valor2["num"])-$g; $i++) {
				$temp .= $valor2["num"][$i];
				echo $valor2["num"][$i]." &nbsp ";
			} //end for
			echo "| &nbsp  ";
			//imprime o restante de num2 (deslocado)
			for ($i=$i;$i<strlen($valor2["num"]);$i++) {
				echo $valor2["num"][$i]." &nbsp ";
			} //end for
			echo " &nbsp x  ".$base."<sup>".$valor1["grau"]."</sup> <br><br>";
			list($int1,$frac1) = explode (".",$valor1["num"]);
			echo "<b>".$msg->get("SOMAPF_MSG_26")." ",$valor1["grau"],":</b> <br><br>";
			$res = base_convert(bcadd(base_convert($frac1,$base,10), base_convert($temp,$base,10)),10,$base);
			if (strlen($res)>$mant) {
				$res = substr_replace($res,".",1,0);
				echo $msg->get("SOMAPF_MSG_27")." = X<sub>1</sub> + X<sub>2</sub> = ".$res." x ".$base."<sup>".$valor1["grau"]."</sup><br><br>";
			} else {
				$res = substr_replace($res,"0.",0,0);
				echo $msg->get("SOMAPF_MSG_27")." = X<sub>1</sub> + X<sub>2</sub> = ".$res." x ".$base."<sup>".$valor1["grau"]."</sup><br><br>";
			}
			echo "<b>".$msg->get("SOMAPF_MSG_28")."</b> <br><br>";
			$grau_anterior=$valor1["grau"];
			$res = normaliza_num($res,$base,$mant,$valor1["grau"]);
			//significa que o numero ja estava normalizado
			if ($grau_anterior == $res["grau"]) {
				echo $msg->get("SOMAPF_MSG_29")."<br><br>";
			} // end if
			$erro = verifica_overflow_underflow($res["grau"],$expmin,$expmax);
			//se nao ocorreu overflow ou underflow
			if ($erro=="ok") {
				//calcular o valor da resposta na base decimal
				$result = base_x_to_decimal($res["num"],$base,$mant,$res["grau"]);
				echo "<b>".$msg->get("SOMAPF_MSG_10")."</b> <br><br>";
				echo "<font color=blue> ".$msg->get("SOMAPF_MSG_27")." = ".$res["num"]." x ".$base."<sup>".$res["grau"]."</sup> =".$result."<br><br></font> ";
			} else {
				echo "<b>".$msg->get("SOMAPF_MSG_10")."</b> <br><br>";
				if ($erro == "erro_over") {
					echo "<font color=red>".$msg->get("SOMAPF_MSG_15")." ".$res["grau"]." > ".$expmax." </font><br>";
				} //end if
				if ($erro == "erro_under") {
					echo "<font color=red>".$msg->get("SOMAPF_MSG_16")." ".$res["grau"]." < ".$expmin." </font><br>";
				} //end if
				echo "<font color=red>".$msg->get("SOMAPF_MSG_30")."<br><br></font>";
			} //end else
		} //end else
	} //end if
} //end function

/* Subtrai dois numeros em ponto flutuante, dado o sistema de ponto flutuante.
 * F = (base,mant,expmin,expmax) e os numeros num1, num2 (em decimal).
 */
function subPF($num1,$num2,$base,$mant,$expmin,$expmax) {
	/* $sinal ira armazenar o sinal do resultado.
	 * + para positivo e - para negativo.
	 * Os dois numeros de entrada sao positivos, o que define o sinal
	 * negativo e o "menos" como operador. Se o segundo numero for
	 * maior que o primeiro, entao o sinal do resultado sempre sera negativo.
	 * Senao, o sinal sempre sera positivo (default).
	 */
    global $msg;
	$sinal = "+";
	$prossegue = "sim";
	echo "<b>".$msg->get("SUBPF_MSG_11")."</b> <br><br>";
	echo "F = (b,m,e<sub>1</sub>,e<sub>2</sub>)<br><br>";
	echo "b = ".$base."&nbsp&nbsp m = ".$mant."&nbsp&nbsp e<sub>1</sub> = ".$expmin."&nbsp&nbsp e<sub>2</sub> = ".$expmax."<br><br>";
	echo "<b>".$msg->get("SUBPF_MSG_12")."</b> <br><br>";
	echo "X<sub>1</sub> = ".$num1."<sub>10</sub><br><br>";
	echo "X<sub>2</sub> = ".$num2."<sub>10</sub><br><br>";
	echo "<b>".$msg->get("SUBPF_MSG_13")." ".$base.":</b> <br><br>";
	$num1 = decimal_to_base_x($num1,$base,$mant);
	$num2 = decimal_to_base_x($num2,$base,$mant);
	echo "X<sub>1</sub> = ".$num1."<sub>".$base."</sub><br><br>";
	echo "X<sub>2</sub> = ".$num2."<sub>".$base."</sub><br><br>";
	echo "<b>".$msg->get("SUBPF_MSG_14")."</b> <br><br>";
	$valor1 = normaliza_num($num1,$base,$mant,0);
	$valor2 = normaliza_num($num2,$base,$mant,0);
	$erro1 = verifica_overflow_underflow($valor1["grau"],$expmin,$expmax);
	$erro2 = verifica_overflow_underflow($valor2["grau"],$expmin,$expmax);
	echo "X<sub>1</sub> = ".$valor1["num"]." x ".$base."<sup>".$valor1["grau"]."</sup>";
	if ($erro1 != "ok") {
		if ($erro1 == "erro_over") {
			echo "<font color=red>".$msg->get("SUBPF_MSG_15")." ".$valor1["grau"]." > ".$expmax." </font>";
		} //end if
		if ($erro1 == "erro_under") {
			echo "<font color=red>".$msg->get("SUBPF_MSG_16")." ".$valor1["grau"]." < ".$expmin." </font>";
		} //end if
		$prossegue = "nao";
	} //end if
	echo "<br><br>";
	echo "X<sub>2</sub> = ".$valor2["num"]." x ".$base."<sup>".$valor2["grau"]."</sup>";
	if ($erro2 != "ok") {
		if ($erro2 == "erro_over") {
			echo "<font color=red>".$msg->get("SUBPF_MSG_15")." ".$valor2["grau"]." > ".$expmax." </font>";
		} //end if
		if ($erro2 == "erro_under") {
			echo "<font color=red>".$msg->get("SUBPF_MSG_16")." ".$valor2["grau"]." < ".$expmin." </font>";
		} //end if
		$prossegue = "nao";
	} //end if
	echo "<br><br>";
	if ( ($valor1["grau"] < $valor2["grau"]) or ( ($valor1["grau"] == $valor2["grau"]) and ($valor1["num"] < $valor2["num"]) ) ) { // verifica se e possivel somar os numeros
		$sinal = "-";
		$aux1 = $valor1["num"];
		$aux2 = $valor1["grau"];
		$valor1["num"] = $valor2["num"];
		$valor1["grau"] = $valor2["grau"];
		$valor2["num"] = $aux1;
		$valor2["grau"] = $aux2;
		echo "<font color=red>".$msg->get("SUBPF_MSG_17")."</font><br><br>";
		echo $msg->get("SUBPF_MSG_18")." <br><br>";
		echo "X<sub>1</sub> = ".$valor1["num"]." x ".$base."<sup>".$valor1["grau"]."</sup><br><br>";
		echo "X<sub>2</sub> = ".$valor2["num"]." x ".$base."<sup>".$valor2["grau"]."</sup><br><br>";
		echo $msg->get("SUBPF_MSG_32")."<br><br>";
		echo "- X<sub>1</sub> + X<sub>2</sub><br><br>";

	} //end if
	if ($prossegue == "nao") {
		echo "<font color=red>".$msg->get("SUBPF_MSG_19")."</font><br><br>";
	} //end if
	if ($prossegue == "sim") {
		echo "<b>".$msg->get("SUBPF_MSG_20")."</b> <br><br>";
		echo "( ".$valor1["num"]." x ".$base."<sup>".$valor1["grau"]."</sup> + ";
		echo $valor2["num"]." x ".$base."<sup>".$valor2["grau"]."</sup> ) <br><br>";
		echo "g = e - f <br>";
		echo "g = (".$valor1["grau"].") - (".$valor2["grau"].") = ".($valor1["grau"] - $valor2["grau"])."<br><br>";
		$g = $valor1["grau"] - $valor2["grau"];
		if ($g >= $mant) { // se g e igual ou maior que a mantissa, entao o resultado sera o valor de x
			echo "<b>".$msg->get("SUBPF_MSG_21")." >= ".$mant." ".$msg->get("SUBPF_MSG_22")."</b><br><br>";
			echo "<font color=blue>".$msg->get("SUBPF_MSG_10")." x<sub>1</sub>= ".$sinal." ".$valor1["num"]." x ".$base."<sup>".$valor1["grau"]."</sup> = ";
			//calcular o valor da resposta na base decimal
			$aux = 1;
			$result = 0;
			for ($j=2; $j<strlen($valor1["num"])-1; $j++) { // percorre cada algarismo da mantissa
				$result = $result +  $valor1["num"][$j] / potencia( $base, $aux);
				$aux++;
			} //end for
			$result = ($result + $valor1["num"][$j]/potencia( $base, $aux) ) * potencia( $base,$valor1["grau"]);
			echo $sinal." ".$result."<br><br></font>";
		} //end if
		else { //caso g seja menor que a mantissa, entao e preciso seguir o seguinte algoritmo
			echo "<b>".$msg->get("SUBPF_MSG_21")." < ".$mant." ".$msg->get("SUBPF_MSG_22")."</b><br><br>";
			echo "<b>".$msg->get("SUBPF_MSG_23")."<br> <br> </b>";
			echo "X<sub>1</sub> = ";
			for ($i=2; $i<strlen($valor1["num"]); $i++) {
				echo $valor1["num"][$i]." &nbsp ";
			} //end for
			echo "| &nbsp  0 .. 0 &nbsp x ".$base."<sup>".$valor1["grau"]."</sup><br>";
			echo "X<sub>2</sub> = ";
			for ($i=2; $i<strlen($valor2["num"]); $i++) {
				echo $valor2["num"][$i]." &nbsp ";
			} //end for
			echo "| &nbsp  0 .. 0 &nbsp x ".$base."<sup>".$valor2["grau"]."</sup><br><br>";
			echo "<b>".$msg->get("SUBPF_MSG_24")." ".$g." ".$msg->get("SUBPF_MSG_25")."<br><br></b>";
			for ($i=0;$i<$g;$i++) { //desloca num2 de g casas a direita
				$valor2["num"] = substr_replace($valor2["num"],"0",2,0);
			} //end for
			echo "X<sub>1</sub> = ";
			for ($i=2; $i<strlen($valor1["num"]); $i++) { //imprime num1
				echo $valor1["num"][$i]." &nbsp ";
			} //end for
			echo "| &nbsp  ";
			for ($i=0;$i<$g;$i++) {  //imprime g 0's depois de num1
				//$valor1["num"] = substr_replace($valor1["num"],"0",strlen($valor1["num"]),0);
				echo "0 &nbsp ";
			} //end for
			echo " &nbsp x ".$base."<sup>".$valor1["grau"]."</sup> <br>";
			$temp = "";
			echo "X<sub>2</sub> = ";
			for ($i=2; $i<strlen($valor2["num"])-$g; $i++) { //imprime os "mant" primeiros digitos de num2 (tamanho da mantissa)
				$temp .= $valor2["num"][$i];
				echo $valor2["num"][$i]." &nbsp ";
			} //end for
			echo "| &nbsp  ";
			for ($i=$i;$i<strlen($valor2["num"]);$i++) { //imprime o restante de num2 (deslocado)
				echo $valor2["num"][$i]." &nbsp ";
			} //end for	
			echo " &nbsp x  ".$base."<sup>".$valor1["grau"]."</sup> <br><br>";
			list($int1,$frac1) = explode (".",$valor1["num"]);
			list($int2,$frac2) = explode (".",$valor2["num"]);
			echo "<b>".$msg->get("SUBPF_MSG_26")." ",$valor1["grau"],":</b> <br><br>";
			//$res = base_convert(bcsub(base_convert($frac1,$base,10),base_convert($temp,$base,10)),10,$base);
            $res = base_convert(base_convert($frac1,$base,10)-base_convert($temp,$base,10),10,$base); //** substituindo a funcao por uma sem a biblioteca bcmath - podem haver complicações **
			// Como a operacao e feita sob as mantissas, elas sao consideradas como numeros inteiros
			// isolados, portanto os zeros nao significativos sao desconsiderados. Esta proxima verificacao
			// evita esse tipo de erro, por exemplo, se $res e 005664 o numero que seria formado,
			// sem essa verificacao, seria 0.5664, o que esta errado.
			if (strlen($res)<$mant) {
				$dif = ($mant)-strlen($res);
				for ($i=0; $i<$dif; $i++) {
					$res = substr_replace($res,"0",0,0);
				}
			}
			// O nico caso em que o tamanho da string da resposta e maior que a mantissa + g (numero de casas 
			// total das mantissas aps o deslocamento do segundo numero) e o caso em que tem-se um
			// nico registrador de carry, que significa que nao faz parte da mantissa do resultado, entao e
			// inserido um "." para separar mantissa de parte inteira.
			if (strlen($res)>$mant+$g) {
				$res = substr_replace($res,".",1,0);
				echo $msg->get("SUBPF_MSG_27")." = ".$sinal." |X<sub>1</sub>| - |X<sub>2</sub>| = ".$sinal." ".$res." x ".$base."<sup>".$valor1["grau"]."</sup><br><br>";
			// Senao a parte inteira e zero, ou seja, e incluido "0."  na variavel da resposta.
			} else {
				$res = substr_replace($res,"0.",0,0);
				echo $msg->get("SUBPF_MSG_27")." = ".$sinal." |X<sub>1</sub>| - |X<sub>2</sub>| = ".$sinal." ".$res." x ".$base."<sup>".$valor1["grau"]."</sup><br><br>";
			}
			echo "<b>".$msg->get("SUBPF_MSG_28")."</b> <br><br>";
			$grau_anterior=$valor1["grau"];
			$res = normaliza_num($res,$base,$mant,$valor1["grau"]);
			//significa que o numero ja estava normalizado
			if ($grau_anterior == $res["grau"]) {
				echo $msg->get("SUBPF_MSG_29")."<br><br>";
			} // end if
			$erro = verifica_overflow_underflow($res["grau"],$expmin,$expmax);
			//se nao ocorreu overflow ou underflow
			if ($erro=="ok") {
				//calcular o valor da resposta na base decimal
				$result = base_x_to_decimal($res["num"],$base,$mant,$res["grau"]);
				echo "<b>".$msg->get("SUBPF_MSG_10")."</b> <br><br>";
				echo "<font color=blue> Subtra&ccedil;&atilde;o = ".$sinal." ".$res["num"]." x ".$base."<sup>".$res["grau"]."</sup> = ".$sinal." ".$result."<br><br></font> ";
			} else {
				echo "<b>".$msg->get("SUBPF_MSG_10")."</b> <br><br>";
				if ($erro == "erro_over") {
					echo "<font color=red>".$msg->get("SUBPF_MSG_15")." ".$res["grau"]." > ".$expmax." </font><br>";
				} //end if
				if ($erro == "erro_under") {
					echo "<font color=red>".$msg->get("SUBPF_MSG_16")." ".$res["grau"]." < ".$expmin." </font><br>";
				} //end if
				echo "<font color=red>".$msg->get("SUBPF_MSG_30")."<br><br></font>";
			} //end else
		} //end else
	} //end if
} //end function

/*  Multiplica dois numeros em ponto flutuante, dado o sistema de ponto flutuante.
 * F = (base,mant,expmin,expmax) e os numeros num1, num2 (em decimal).
 */
function multPF($num1,$num2,$base,$mant,$expmin,$expmax) {
    global $msg;
	$prossegue = "sim";
	echo "<b>".$msg->get("MULTPF_MSG_11")."</b> <br><br>";
	echo "F = (b,m,e<sub>1</sub>,e<sub>2</sub>)<br><br>";
	echo "b = ".$base."&nbsp&nbsp m = ".$mant."&nbsp&nbsp e<sub>1</sub> = ".$expmin."&nbsp&nbsp e<sub>2</sub> = ".$expmax."<br><br>";
	echo "<b>".$msg->get("MULTPF_MSG_12")."</b> <br><br>";
	echo "X<sub>1</sub> = ".$num1."<sub>10</sub><br><br>";
	echo "X<sub>2</sub> = ".$num2."<sub>10</sub><br><br>";
	echo "<b>".$msg->get("MULTPF_MSG_13")." ".$base.":</b> <br><br>";
	$num1 = decimal_to_base_x($num1,$base,$mant);
	$num2 = decimal_to_base_x($num2,$base,$mant);
	echo "X<sub>1</sub> = ".$num1."<sub>".$base."</sub><br><br>";
	echo "X<sub>2</sub> = ".$num2."<sub>".$base."</sub><br><br>";
	echo "<b>".$msg->get("MULTPF_MSG_14")."</b> <br><br>";
	$valor1 = normaliza_num($num1,$base,$mant,0);
	$valor2 = normaliza_num($num2,$base,$mant,0);
	$erro1 = verifica_overflow_underflow($valor1["grau"],$expmin,$expmax);
	$erro2 = verifica_overflow_underflow($valor2["grau"],$expmin,$expmax);
	echo "X<sub>1</sub> = ".$valor1["num"]." x ".$base."<sup>".$valor1["grau"]."</sup>";
	if ($erro1 != "ok") {
		if ($erro1 == "erro_over") {
			echo "<font color=red>".$msg->get("MULTPF_MSG_15")." ".$valor1["grau"]." > ".$expmax." </font>";
		} //end if
		if ($erro1 == "erro_under") {
			echo "<font color=red>".$msg->get("MULTPF_MSG_16")." ".$valor1["grau"]." < ".$expmin." </font>";
		} //end if
		$prossegue = "nao";
	} //end if
	echo "<br><br>";
	echo "X<sub>2</sub> = ".$valor2["num"]." x ".$base."<sup>".$valor2["grau"]."</sup>";
	if ($erro2 != "ok") {
		if ($erro2 == "erro_over") {
			echo "<font color=red>".$msg->get("MULTPF_MSG_15")." ".$valor2["grau"]." > ".$expmax." </font>";
		} //end if
		if ($erro2 == "erro_under") {
			echo "<font color=red>".$msg->get("MULTPF_MSG_16")." ".$valor2["grau"]." < ".$expmin." </font>";
		} //end if
		$prossegue = "nao";
	} //end if
	echo "<br><br>";
	if ($prossegue == "nao") {
		echo "<font color=red>".$msg->get("MULTPF_MSG_17")."</font><br><br>";
	} //end if
	if ($prossegue == "sim") {
		echo "<b>".$msg->get("MULTPF_MSG_18")."</b> <br><br>";
		echo "<b>".$msg->get("MULTPF_MSG_19")." X<sub>1</sub> com X<sub>2</sub> ".$msg->get("MULTPF_MSG_20")."</b> <br><br>";
		echo "( ".$valor1["num"]." x ".$base."<sup>".$valor1["grau"]."</sup> x ";
		echo $valor2["num"]." x ".$base."<sup>".$valor2["grau"]."</sup> ) <br><br>";
		echo "g = e + f <br>";
		echo "g = (".$valor1["grau"].") + (".$valor2["grau"].") = ".($valor1["grau"] + $valor2["grau"])."<br><br>";
		$g = $valor1["grau"] + $valor2["grau"];
		list ($int1,$frac1) = explode(".",$valor1["num"]);
		list ($int2,$frac2) = explode(".",$valor2["num"]);
		$temp1 = decimal_to_base_x($valor1["num"],$base,$mant);
		$temp2 = decimal_to_base_x($valor2["num"],$base,$mant);
		$res = base_convert((base_convert($frac1,$base,10) * base_convert($frac2,$base,10)),10,$base);
		$numero_casas = $mant + $mant; //numero de casas decimais da resposta
                /*a multiplicacao e apenas das mantissas, entao para formar o numero
                 *com a parte inteira e decimal e preciso completar a mantissa com os 0's que faltam.
		 */
		if (strlen($res)<$numero_casas) {
			$dif = $numero_casas - strlen($res);
			for ($i=0;$i<$dif;$i++) {
			      $res = substr_replace($res,"0",0,0);
			}
		}
		$res = substr_replace($res,"0.",0,0);
		echo "X<sub>1</sub> x X<sub>2</sub> = ".$res."<br><br>";
		echo $msg->get("MULTPF_MSG_21")." ".$res." x ".$base."<sup>".$g."</sup><br><br>";
		echo "<b>".$msg->get("MULTPF_MSG_22")."</b> <br><br>";
		$grau_anterior = $g;
		$res = normaliza_num($res,$base,$mant,$g);
		//significa que o numero ja estava normalizado
		if ($grau_anterior == $res["grau"]) {
			echo $msg->get("MULTPF_MSG_23")."<br><br>";
		} // end if
		$erro = verifica_overflow_underflow($res["grau"],$expmin,$expmax);
		//se nao ocorreu overflow ou underflow
		if ($erro=="ok") {
			//calcular o valor da resposta na base decimal
			$result = base_x_to_decimal($res["num"],$base,$mant,$res["grau"]);
			echo "<b>".$msg->get("MULTPF_MSG_10")."</b> <br><br>";
			echo "<font color=blue> ".$res["num"]." x ".$base."<sup>".$res["grau"]."</sup> =".$result."<br><br></font> ";
		} else {
			echo "<b>".$msg->get("MULTPF_MSG_10")."</b> <br><br>";
			if ($erro == "erro_over") {
				echo "<font color=red>".$msg->get("MULTPF_MSG_15")." ".$res["grau"]." > ".$expmax." </font><br>";
			} //end if
			if ($erro == "erro_under") {
				echo "<font color=red>".$msg->get("MULTPF_MSG_16")." ".$res["grau"]." < ".$expmin." </font><br>";
			} //end if
			echo "<font color=red>".$msg->get("MULTPF_MSG_24")."<br><br></font>";
		} //end else
	} //end if
} //end function

/* Divide dois numeros em ponto flutuante, dado o sistema de ponto flutuante.
 * F = (base,mant,expmin,expmax) e os numeros num1, num2 (em decimal).
 */
function divPF($num1,$num2,$base,$mant,$expmin,$expmax) {
    global $msg;
	$prossegue = "sim";
	echo "<b>".$msg->get("DIVPF_MSG_11")."</b> <br><br>";
	echo "F = (b,m,e<sub>1</sub>,e<sub>2</sub>)<br><br>";
	echo "b = ".$base."&nbsp&nbsp m = ".$mant."&nbsp&nbsp e<sub>1</sub> = ".$expmin."&nbsp&nbsp e<sub>2</sub> = ".$expmax."<br><br>";
	echo "<b>".$msg->get("DIVPF_MSG_12")."</b> <br><br>";
	echo "X<sub>1</sub> = ".$num1."<sub>10</sub><br><br>";
	echo "X<sub>2</sub> = ".$num2."<sub>10</sub><br><br>";
	echo "<b>".$msg->get("DIVPF_MSG_13")." ".$base.":</b> <br><br>";
	$num1 = decimal_to_base_x($num1,$base,$mant);
	$num2 = decimal_to_base_x($num2,$base,$mant);
	echo "X<sub>1</sub> = ".$num1."<sub>".$base."</sub><br><br>";
	echo "X<sub>2</sub> = ".$num2."<sub>".$base."</sub><br><br>";
	echo "<b>".$msg->get("DIVPF_MSG_14")."</b> <br><br>";
	$valor1 = normaliza_num($num1,$base,$mant,0);
	$valor2 = normaliza_num($num2,$base,$mant,0);
	$erro1 = verifica_overflow_underflow($valor1["grau"],$expmin,$expmax);
	$erro2 = verifica_overflow_underflow($valor2["grau"],$expmin,$expmax);
	echo "X<sub>1</sub> = ".$valor1["num"]." x ".$base."<sup>".$valor1["grau"]."</sup>";
	if ($erro1 != "ok") {
		if ($erro1 == "erro_over") {
			echo "<font color=red>".$msg->get("DIVPF_MSG_15")." ".$valor1["grau"]." > ".$expmax." </font>";
		} //end if
		if ($erro1 == "erro_under") {
			echo "<font color=red>".$msg->get("DIVPF_MSG_16")." ".$valor1["grau"]." < ".$expmin." </font>";
		} //end if
		$prossegue = "nao";
	} //end if
	echo "<br><br>";
	echo "X<sub>2</sub> = ".$valor2["num"]." x ".$base."<sup>".$valor2["grau"]."</sup>";
	if ($erro2 != "ok") {
		if ($erro2 == "erro_over") {
			echo "<font color=red>".$msg->get("DIVPF_MSG_15")." ".$valor2["grau"]." > ".$expmax." </font>";
		} //end if
		if ($erro2 == "erro_under") {
			echo "<font color=red>".$msg->get("DIVPF_MSG_16")." ".$valor2["grau"]." < ".$expmin." </font>";
		} //end if
		$prossegue = "nao";
	} //end if
	echo "<br><br>";
	if ($prossegue == "nao") {
		echo "<font color=red>".$msg->get("DIVPF_MSG_17")."</font><br><br>";
	} //end if
	if ($prossegue == "sim") {
		echo "<b>".$msg->get("DIVPF_MSG_18")."</b> <br><br>";
		echo "<b>".$msg->get("DIVPF_MSG_19")." X<sub>1</sub> com X<sub>2</sub> ".$msg->get("DIVPF_MSG_20")."</b> <br><br>";
		echo "( ".$valor1["num"]." x ".$base."<sup>".$valor1["grau"]."</sup> x ";
		echo $valor2["num"]." x ".$base."<sup>".$valor2["grau"]."</sup> ) <br><br>";
		echo "g = e - f <br>";
		echo "g = (".$valor1["grau"].") - (".$valor2["grau"].") = ".($valor1["grau"] - $valor2["grau"])."<br><br>";
		$g = $valor1["grau"] - $valor2["grau"];
		list ($int1,$frac1) = explode(".",$valor1["num"]);
		list ($int2,$frac2) = explode(".",$valor2["num"]);
		$res = decimal_to_base_x((base_x_to_decimal($valor1["num"],$base,$mant,0) /
		                                        base_x_to_decimal($valor2["num"],$base,$mant,0)),$base,$mant);
		$res .= "";
                /*a multiplicacao e apenas das mantissas, entao para formar o numero
                 *com a parte inteira e decimal e preciso completar a mantissa com os 0's que faltam.
		 */
		echo "X<sub>1</sub> / X<sub>2</sub> = ".$res."<br><br>";
		echo $msg->get("DIVPF_MSG_21")." ".$res." x ".$base."<sup>".$g."</sup><br><br>";
		echo "<b>".$msg->get("DIVPF_MSG_22")."</b> <br><br>";
		$grau_anterior = $g;
		$res = normaliza_num($res,$base,$mant,$g);
		//significa que o numero ja estava normalizado
		if ($grau_anterior == $res["grau"]) {
			echo $msg->get("DIVPF_MSG_23")."<br><br>";
		} // end if
		$erro = verifica_overflow_underflow($res["grau"],$expmin,$expmax);
		//se nao ocorreu overflow ou underflow
		if ($erro=="ok") {
			//calcular o valor da resposta na base decimal
			$aux = 1;
			$result = 0;
			for ($j=2; $j<strlen($res["num"])-1; $j++) { // percorre cada algarismo da mantissa
				$result = $result +  $res["num"][$j] / potencia( $base, $aux);
				$aux++;
			} //end for
			$result = ($result + $res["num"][$j]/potencia( $base, $aux) ) * potencia( $base, $res["grau"]);
			echo "<b>".$msg->get("DIVPF_MSG_10")."</b> <br><br>";
			echo "<font color=blue> ".$res["num"]." x ".$base."<sup>".$res["grau"]."</sup> =".$result."<br><br></font> ";
		} else {
			echo "<b>".$msg->get("DIVPF_MSG_10")."</b> <br><br>";
			if ($erro == "erro_over") {
				echo "<font color=red>".$msg->get("DIVPF_MSG_15")." ".$res["grau"]." > ".$expmax." </font><br>";
			} //end if
			if ($erro == "erro_under") {
				echo "<font color=red>".$msg->get("DIVPF_MSG_16")." ".$res["grau"]." < ".$expmin." </font><br>";
			} //end if
			echo "<font color=red>".$msg->get("DIVPF_MSG_24")." <br><br></font>";
		} //end else
	} //end if
} //end function
function verificaBib($idm)
{
    global $msg;
?>
        <form name="selbib" enctype="multipart/form-data" method="post" action="index.php?inc=sistemaPF.php&modo=exemplo">
        <br><b><?php echo $msg->get("Biblioteca_Utilizada") ?>:</b>
        <select name="id_bib" size="1" onchange="document.selbib.submit()">
        <?php    //oferece a opcao de visualizar exemplos de outro professor
                ListaBibliotecas();
        ?>
        </select>
        <p>
        <input type="hidden" name="document_root" value="<? echo $DOCUMENT_ROOT ?>">
        </form>
<?php
    echo "<br>";
}

?>
